home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
comm
/
message.zip
/
ARTICLE.ASC
next >
Wrap
Text File
|
1992-11-10
|
23KB
|
496 lines
MESSAGE MINDER
Windows 3.x is all the rage these days, and it seems
that plain old DOS has become passe, right? Well, there has
never been a more inaccurate statement. I use DOS
exclusively, as does most everyone else I know. The latest
Windows craze also makes it difficult for new programmers to
"catch up" to top notch programmers because all the journals
are singing the praises of Windows, with little attention
paid to programming in DOS. I am a college student speaking
from experience here. I found it necessary to go through
magazines five years old to catch up to what people are
talking about in the various programming journals published
today!
The most difficult topic of DOS programming was also the
most difficult thing for me to find information on: Terminate
and Stay Resident programs, or TSRs. Another area which many
programmers find daunting is dealing with the PC's serial
port. Well, here is a program I wrote which deals with BOTH
concepts. If TSR programming is old hat to you, perhaps you
might find the code which uses the serial port of interest.
THE PROGRAM: What does it do?
When I decided to undertake the creation of a TSR
utility, I didn't want another "me too" note pad or it's
ilk; I wanted to create something I hadn't seen before. My
program, simply called "message", will allow messages to be
exchanged between two computers connected by their serial
ports with a null modem cable. If "message" is loaded on both
machines, a two-way conversation can take place. No longer
would it be necessary to walk from your office to a friend's
to remind her of a lunch date, or to ask for quick advice.
Once "message" is loaded it records the message strings
from the sending computer and displays them in a window at
the upper left corner of the screen when the entire message
is received. It will then pause until the user presses a
key. To send a message the user would press the hot-key
<ctrl> w, resulting in a window being displayed at the top of
the screen. Type in your message here, followed by return.
If you would prefer to load "message" on only one
machine, messages could (optionally) be sent by the quick and
dirty program I wrote called "send". It's use could not be
simpler:
C:\send Well, do you think Clinton will win?
Send works by taking each command line argument (the words of
your message) and copying them into a single string. The
string is then sent out the serial port, one character at a
time.
To un-install the program the user would enter the
following:
C:\message u
THE SERIAL PORT: It isn't really THAT bad!
OK! Before delving into how to make a TSR I feel
compelled by guilt to talk a little about the serial port.
PLEASE NOTE that this article is about TSR programming, and
the information provided on the serial port is intended to
give you an idea of how that portion of the program
functions.
Two things in the program listing that you should be
looking at are 1) the serial() function in "Message", and
2) the "Send" program.
If you don't really care how the serial port works you
still need to know how to connect two machines together for
"Message" to work. You can let someone rip you off by paying
far too much for a null modem connector, or you can be frugal
and make something yourself. Here is how:
Serial ports come in two flavors: 9 pin connectors and
25 pin connectors. Both serve the same function, the 9 pin
just eliminates the unnecessary connections. In order for
"Message" to work you will only need to run two wires between
the two machines. The other wires are there to communicate
with your modem so "Message" does not need them.
On a 25 pin connector pin 2 is used to transmit data,
and pin 3 is used to receive data; on a 9 pin connector pin 2
is used to receive data and pin 3 is used to transmit data.
Two connect two PCs with the same type of serial connector
together, run a wire from pin 2 of each machine to pin 3 of
the other machine. I also recommend that you connect the
ground pins (pin 7 on a 25 pin connector) of each PC
together. "Message" will usually work without connecting the
ground pins, but it is a good (and safe) practice to connect
them.
Connectivity aside, how does one send and receive
characters with the serial port? One possible method is the
use of the BIOS, but it is far too slow. For any real speed
we must directly use the PCs UART. UART stands for Universal
Asynchronous Receiver-Transmitter.
The UART is a chip inside of your computer, generally
the 8250. You talk to this chip via port addresses. A port
address is similar to a memory location except it is
connected to some external hardware. The base port address
of the PCs first serial card (COM 1) is usually 3F8 hex.
Like your microprocessor, the 8250 has internal registers.
You access these registers by their port address. 3F8 is
called the base address because it is the location of the
first register. The second register would be located at port
3F9, etc...
THE WORKINGS OF A TSR PROGRAM.
The first thing "message" does when it is loaded is to
determine how much memory it occupies. This information will
be saved so that when the program terminates it can tell DOS
how much memory to reserve for it.
Before we undertake the task of determining the size of
the program a word or two should be said about the PSP, or
Program Segment Prefix. When DOS loads a program into memory
it creates a 256 byte block of memory containing information
about that program. This block of memory always starts at
offset 0000. As assembly language programmers know, code
usually starts after the PSP at offset 100h, 256 decimal.
In Microsoft C there exists a global variable _psp which
contains the segment address of the PSP of the current
program. With this information we now know where in memory
"message" begins. "Message" takes advantage of this right
away by setting the huge pointer tsrbottom to point to
_psp:0000. This address is where our program starts. A huge
pointer is used so that C will do our pointer arithmetic for
us.
Programs created with Microsoft C in the small memory
model are followed in memory by their stack space, then the
heap space used for run-time memory allocation. NOTE -
Borland swaps the heap and the stack area! With Microsoft C
the address pointed to by SP:SS plus a maximum heap size is
an effective estimate for the end of the program; For
Borland the end of your program is simply SP:SS. To obtain
this information you must have access to register values.
"Message" accomplishes this by using the Microsoft _asm
keyword. The following lines , taken from "Message", will
copy the stack address into the huge character pointer
tsrstack:
137 _asm mov WORD PTR tsrstack[0], sp // save stack ptr
138 _asm mov WORD PTR tsrstack[2], ss // and stack seg
Then establish a far pointer to our PSP.
139 FP_SEG(tsrbottom) = _psp; // save PSP segment
140 FP_OFF(tsrbottom) = 0; // offset of 0
To obtain the program size in bytes simply subtract the
PSP address from the stack address, and add to this byte
value to maximum amount of memory you will allocate with
malloc(). DOS expects this value in paragraphs, not bytes.
This makes it necessary to divide our byte size by 16. This
can easily be accomplished by shifting the byte value 4 bits
to the right (2 ^ 4 = 16).
Here is how "Message" does it:
141 tsrsize = ((tsrstack - tsrbottom) >> 4) + 1;
Another useful consequence of saving our stack address
is that when our TSR is activated we can use our own stack,
rather than using the stack of the interrupted process. This
is beneficial because we have no way of knowing how much
stack space is left in the process we are interrupting. The
doit() function shows how setting up the stack can be
accomplished.
Whew! The next procedure "Message" undertakes is the